package xin.sunzy.spring.intercept;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import xin.sunzy.spring.constant.Constants;
import xin.sunzy.spring.model.User;
import xin.sunzy.spring.service.UserService;
import xin.sunzy.spring.util.UserUtils;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

/**
 * @description: 用户登录拦截器
 * @email: <a href="sunzhenyu@terminus.io">孙振宇</a>
 * @author: ginkgo
 * @date: 2018/4/2
 */
public class UserLoginIntercept extends HandlerInterceptorAdapter {

    /**
     * 用户缓存
     */
    private LoadingCache<Long, User> userCache;

    @Autowired
    private UserService userService;

    public UserLoginIntercept() {
    }

    @PostConstruct
    public void init() {
        userCache = CacheBuilder.newBuilder()
                .expireAfterWrite(30, TimeUnit.MINUTES)
                .build(new CacheLoader<Long, User>() {
                    @Override
                    public User load(Long id) {
                        return userService.findById(id);
                    }
                });
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession(false);
        if (session != null) {
            Object userIdInSession = session.getAttribute(Constants.SESSION_USER_ID);
            if (userIdInSession != null) {
                final Long userId = Long.valueOf(userIdInSession.toString());
                User user = userCache.getUnchecked(userId);
                if (user != null) {
                    UserUtils.putCurrentUser(user);
                }
            }
            Object locale = session.getAttribute(Constants.USER_LOCALE);
            if (locale != null && locale instanceof Locale) {
                final Locale currentLocale = (Locale) locale;
                if (currentLocale != null) {
                    UserUtils.putCurrentLocale(currentLocale);
                }
            } else {
                UserUtils.putCurrentLocale(LocaleContextHolder.getLocale());
            }
        }
        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
        UserUtils.clearCurrentUser();
    }

    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        super.afterConcurrentHandlingStarted(request, response, handler);
    }
}
